package pdfsetter.ui;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import pdfsetter.core.XMLObjectSerializer;
import pdfsetter.core.pages.PageInfo;
import pdfsetter.core.pages.PageRectangle;
import pdfsetter.core.pages.PageType;
import pdfsetter.core.schema.AutomaticDocumentSchemaPattern;
import pdfsetter.core.schema.DocumentSchemaPattern;
import pdfsetter.core.schema.SimpleDocumentSchemaPattern;
import pdfsetter.core.schema.SinglePageSchema;
import pdfsetter.core.schema.advanced.AttachedFilePageSelector;
import pdfsetter.core.schema.advanced.AutomaticConsecutiveProcessPattern;
import pdfsetter.core.schema.advanced.AutomaticRepetitiveProcessPattern;
import pdfsetter.core.schema.advanced.ConsecutiveFileListProcessPattern;
import pdfsetter.core.schema.advanced.FilePageSelector;
import pdfsetter.core.schema.advanced.FillingSchemaPattern;
import pdfsetter.core.schema.advanced.RepetitiveFileListProcessPattern;
import pdfsetter.core.schema.onefile.OneFileDocumentSchemaPattern;
import pdfsetter.core.schema.onefile.SimpleOneFileDocumentSchemaPattern;
import pdfsetter.core.schema.selectors.CompoundFilePageSelector;
import pdfsetter.core.schema.selectors.LeapingPageSelector;
import pdfsetter.core.schema.selectors.NormalPageSelector;
import pdfsetter.core.schema.selectors.RangePageSelector;

import com.thoughtworks.xstream.XStreamException;

/**
 * This class represents program which writes templates to the given location. Unfortunately it is not very clear and it could be written in more elegant form.
 * 
 * @author Andrzej Dorobisz
 */
public class WriteExamples {
    private final XMLObjectSerializer serializer;
    private String dir = "";

    public WriteExamples(XMLObjectSerializer serializer) {
        this.serializer = serializer;
    }

    private void saveSomeExamples() throws XStreamException, FileNotFoundException {
        System.out.println("Writing single page schemas:");
        PageInfo a4 = new PageInfo(PageType.A4);
        ArrayList<PageRectangle> loc0 = new ArrayList<PageRectangle>();
        loc0.add(new PageRectangle(0, 0, a4.getWidth(), a4.getHeight(), 0));
        SinglePageSchema normalA4 = new SinglePageSchema("Normal A4", a4, loc0);

        serializer.writeObject(normalA4, dir + "normal_A4.xml");
        System.out.println("\t- normal, one page on A4");

        PageInfo a4page = new PageInfo(PageType.A4).rotate();
        ArrayList<PageRectangle> locations = new ArrayList<PageRectangle>();
        locations.add(new PageRectangle(0, 0, a4page.getWidth() / 2, a4page.getHeight(), 0));
        locations.add(new PageRectangle(a4page.getWidth() / 2, 0, a4page.getWidth() / 2, a4page.getHeight(), 0));
        SinglePageSchema twoOnA4 = new SinglePageSchema("2xA5 on A4", a4page, locations);

        serializer.writeObject(twoOnA4, dir + "two_A5_on_A4.xml");
        System.out.println("\t- two A5 on A4");

        ArrayList<PageRectangle> loc = new ArrayList<PageRectangle>();
        loc.add(new PageRectangle(0, 0, a4.getWidth() / 2, a4.getHeight() / 2, 0));
        loc.add(new PageRectangle(a4.getWidth() / 2, 0, a4.getWidth() / 2, a4.getHeight() / 2, 0));
        loc.add(new PageRectangle(0, a4.getHeight() / 2, a4.getWidth() / 2, a4.getHeight() / 2, 0));
        loc.add(new PageRectangle(a4.getWidth() / 2, a4.getHeight() / 2, a4.getWidth() / 2, a4.getHeight() / 2, 0));
        SinglePageSchema fourOnA4 = new SinglePageSchema("4xA6 on A4", a4, loc);

        serializer.writeObject(fourOnA4, dir + "four_A6_on_A4.xml");
        System.out.println("\t- four A6 on A4");

        System.out.println("Writing filling schemas:");
        FilePageSelector normal = new NormalPageSelector();
        FillingSchemaPattern joinAll = new AutomaticConsecutiveProcessPattern(normal);
        FillingSchemaPattern mixAll = new AutomaticRepetitiveProcessPattern(normal);

        serializer.writeObject(joinAll, dir + "joinAll.xml");
        System.out.println("\t- join all files");
        serializer.writeObject(mixAll, dir + "mixAll.xml");
        System.out.println("\t- mix all files (take pages from files repetitively)");

        List<AttachedFilePageSelector> atchList = new LinkedList<AttachedFilePageSelector>();
        atchList.add(new AttachedFilePageSelector(normal, 0));
        atchList.add(new AttachedFilePageSelector(normal, 1));
        FillingSchemaPattern joinTwo = new ConsecutiveFileListProcessPattern(atchList);
        FillingSchemaPattern mixTwo = new RepetitiveFileListProcessPattern(atchList);

        serializer.writeObject(joinTwo, dir + "joinTwo.xml");
        System.out.println("\t- join two files");
        serializer.writeObject(mixTwo, dir + "mixTwo.xml");
        System.out.println("\t- mix two files");

        FilePageSelector leapTwo = new LeapingPageSelector(2);
        List<AttachedFilePageSelector> atchList2 = new LinkedList<AttachedFilePageSelector>();
        atchList2.add(new AttachedFilePageSelector(leapTwo, 0));
        FillingSchemaPattern onlyOdd = new ConsecutiveFileListProcessPattern(atchList2);

        List<AttachedFilePageSelector> atchList3 = new LinkedList<AttachedFilePageSelector>();
        atchList3.add(new AttachedFilePageSelector(new CompoundFilePageSelector(new RangePageSelector(1), leapTwo), 0));
        FillingSchemaPattern onlyEven = new ConsecutiveFileListProcessPattern(atchList3);

        serializer.writeObject(onlyOdd, dir + "oneFile_onlyOddPages.xml");
        System.out.println("\t- take only add pages from one file");
        serializer.writeObject(onlyEven, dir + "oneFile_onlyEvenPages.xml");
        System.out.println("\t- take only even pages from one file");

        System.out.println("Writing document schemas:");
        DocumentSchemaPattern simpleJoin = new SimpleDocumentSchemaPattern(twoOnA4, joinAll);
        serializer.writeObject(simpleJoin, dir + "joinAll_2in1_doc.xml");
        System.out.println("\t- join all files and set pages in pattern two A5 on A4");

        List<OneFileDocumentSchemaPattern> ofDocPat = new LinkedList<OneFileDocumentSchemaPattern>();
        ofDocPat.add(new SimpleOneFileDocumentSchemaPattern(normalA4, new RangePageSelector(0, 0)));
        ofDocPat.add(new SimpleOneFileDocumentSchemaPattern(fourOnA4, new RangePageSelector(1)));
        DocumentSchemaPattern autChapters = new AutomaticDocumentSchemaPattern(ofDocPat);

        serializer.writeObject(autChapters, dir + "auto_first-A4_rest-4in1_doc.xml");
        System.out.println("\t- process consecutive files, take first page and place it on a4, than take remaining and set them four on A4");
    }

    public void process(String path) {
        if (path != null) {
            if (!path.endsWith("/"))
                path = path + '/';
            dir = path;
        }
        try {
            System.out.println("Writing some patterns:");
            saveSomeExamples();
            System.out.println("All patterns successfully saved.");
        } catch (XStreamException e) {
            System.out.println("Error while saving patterns.");
        } catch (FileNotFoundException e) {
            System.out.println("Cannot access given location.");
        }
    }
}